using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;



namespace ScriptEase
{
    /// <summary>
    /// The <c>DirectMap</c> computes the a local file mapping 
    /// that directly relates to the WebResource webResourceName (1:1 mapping).
    /// </summary>
    internal class DirectMap : IWorkspaceMapper
    {
        private Workspace _workspace;
        private readonly List<string> _prefixes;



        public DirectMap(  IEnumerable<string> prefixes)
        {
            _prefixes = prefixes.OrderByDescending(p => p.Length).ToList();
            Trace.Default.Info("Publisher prefixes='{0}'", String.Join(";", _prefixes));            
        }



        public void Initialize(Workspace workspace)
        {
            _workspace = workspace;
        }



        /// <summary>
        /// Gets the WebResource default filename.
        /// </summary>
        /// <remarks>
        /// a) WebResource.Name + WebResource.Ext<br/>
        /// If WebResource.Name contains a path then the prefixes are 
        /// removed at the beginning of this path.
        /// </remarks>
        string IWorkspaceMapper.GetFilePath(WebResource webResource)
        {
            // compute the WebResource filepath 
            // the web resource webResourceName may contain '/' and we have to convert into a path with '\' anyway
            Trace.Default.Debug("Computing filepath for webresource '{0}'", webResource.Name);

            string directoryPart = getDirectoryPart(webResource.Name);
            Trace.Default.Debug("Webresource directory part='{0}'", directoryPart);
            directoryPart = FileNDirectory.AlignDirectoryName(directoryPart);

            string webResourceRelativeDirectoryName = 
                ( Path.GetDirectoryName(directoryPart) ?? String.Empty);
            Trace.Default.Debug("Webresource directory name='{0}'", webResourceRelativeDirectoryName);

            string webResourceFileName =
                FileNDirectory.AlignFileName(webResource.Name.Remove(0, directoryPart.Length));
            Trace.Default.Debug("Webresource filename name='{0}'", webResourceFileName);

            string webResourceRelativePath = Path.Combine(webResourceRelativeDirectoryName, webResourceFileName);
            Trace.Default.Debug("Webresource relative path='{0}'", webResourceRelativePath);

            /*  msc, commented out: Web-Resources should definitely have the 
             * filename extension in the web-resource webResourceName!
             * Everything else causes conflicts when referencing web-resources.
             * 
            //
            // check if the WebResource webResourceName ends with one of the allowed extensions for 
            // the current WebResource. If yes, take the WebResource webResourceName as the filename
            // otherwise add extension[0] (the default extensions) to the WebResource webResourceName 
            // to compute a default filename.
            //
            string[] extensions = webResource.GetDesc().FileExtenstions;
            string existingExtension = Path.GetExtension(relativePath);

            //
            // --> check if the file has a valid extension
            // otherwise add the default extension
            //
            if (string.IsNullOrWhiteSpace(existingExtension) || extensions.All(e => !string.Equals(e, existingExtension, StringComparison.InvariantCultureIgnoreCase)))
            {
                // no or invalid extension ==> use default extension 
                relativePath += extensions[0];
            }
            */


            
            // Removed publisher prefixes as a directory information
            foreach (string removePublisherPrefix in _prefixes)
            {
                string publisherDirectory = removePublisherPrefix.Replace("/", @"\") + @"\";
                if (!webResourceRelativePath.StartsWith(publisherDirectory)) continue;
                webResourceRelativePath = webResourceRelativePath.Remove(0, publisherDirectory.Length);
                Trace.Default.Debug("Webresource relative path publisher prefixes removed='{0}'", webResourceRelativePath);
                break;
            }

            Trace.Default.Debug("Computing full path {0} \\ {1}", webResourceRelativePath, _workspace.WebResourcesBasePath);
            return Workspace.GetFullPath(webResourceRelativePath, _workspace.WebResourcesBasePath);
        }



        /// <summary>
        /// Gets the directory part of a webresource name.
        /// </summary>
        private string getDirectoryPart(string webResourceName)
        {
            int p = webResourceName.LastIndexOf("/", StringComparison.OrdinalIgnoreCase);
            if (p < 0) p = webResourceName.LastIndexOf("\\", StringComparison.OrdinalIgnoreCase);

            return p < 0 ? String.Empty : webResourceName.Substring(0, p+1);
        }
    }
}